/********************************************************************************
 *    Copyright (C) 2019 Quark Matter Research Center, IMP,CAS			*
 *                                                                              *
 *              This software is distributed under the terms of the             *
 *              GNU Lesser General Public Licence (LGPL) version 3,             *
 *                  copied verbatim in the file "LICENSE"                       *
 ********************************************************************************/
// in root all sizes are given in cm




#include "TSystem.h"
#include "TGeoManager.h"
#include "TGeoVolume.h"
#include "TGeoMaterial.h"
#include "TGeoMedium.h"
#include "TGeoPgon.h"
#include "TGeoMatrix.h"
#include "TGeoCompositeShape.h"
#include "TFile.h"
#include "TString.h"
#include "TList.h"
#include "TROOT.h"



#include <iostream>

using namespace TMath;
const double pi=TMath::Pi();
double RtoD(double a){return a*180/pi;} // Rad to Degree.

const double thickness_MWDC=20; //thickness of MWDC.
const double theta1=pi/6.; //the up-limit of the acceptence angle.
const double theta2=pi/36.; //the low-limit of the acceptence angle.
const double theta3=(theta1+theta2)/2.; //the angle of middle line for acceptence area.
const double x_c=-10; //The coordinate of collision point.

const double x[3]={315, 365, 415}; //these are the z coordinates of the middle points (at the further edge) of MWDC boxes.
double Hlength_MWDC[3];
double Hheight_MWDC[3];


// Name of geometry version and output file
TString geoPath = gSystem->Getenv("VMCWORKDIR");
const TString geoVersion = "mwdc";
const TString FileName = geoPath+"/geometry/"+geoVersion + ".root";
const TString FileName1 = geoPath+"/geometry/"+geoVersion + "_geomanager.root";

// Names of the different used materials which are used to build the modules
// The materials are defined in the global media.geo file
const TString KeepingVolumeMedium     = "carbondioxide";
const TString MWDCVolumeMedium         = "GEMmixture";

// some global variables
TGeoManager* gGeoMan = NULL;  // Pointer to TGeoManager instance

// Forward declarations
void create_materials_from_media_file();

void Create_MWDC(){
	
	double xc[3]; //these are the z coordinates of the middle points (at the center) of MWDC boxes.
	xc[0]=x[0]-thickness_MWDC/2.*Cos(theta3);
	xc[1]=x[1]-thickness_MWDC/2.*Cos(theta3);
	xc[2]=x[2]-thickness_MWDC/2.*Cos(theta3);

	create_materials_from_media_file();
	gGeoMan=(TGeoManager*)gROOT->FindObject("FAIRGeom");
	gGeoMan->SetVisLevel(7);

	TGeoVolume* topMWDC= new TGeoVolumeAssembly("TOPMWDC");
	gGeoMan->SetTopVolume(topMWDC);

	TGeoVolume* mwdc= new TGeoVolumeAssembly(geoVersion);
	topMWDC->AddNode(mwdc, 1);
	TGeoMedium* MWDCVolMed   = gGeoMan->GetMedium(MWDCVolumeMedium);
//	TGeoMedium* MWDCVolMed   = gGeoMan->GetMedium("air");

	/****** MWDC geometry ******/
	Hlength_MWDC[0]=(x[0]-x_c)/Cos(theta3)*Tan((theta1-theta2)/2.);//The half length of the 1st MWDC box.
	Hlength_MWDC[1]=(x[1]-x_c)/Cos(theta3)*Tan((theta1-theta2)/2.);//The half length of the 2nd MWDC box.
	Hlength_MWDC[2]=(x[2]-x_c)/Cos(theta3)*Tan((theta1-theta2)/2.);//The half length of the 3rd MWDC box.
	Hheight_MWDC[0]=0.8*Hlength_MWDC[0];//The half height of the 1rd MWDC box.
	Hheight_MWDC[1]=0.8*Hlength_MWDC[1];//The half height of the 2rd MWDC box.
	Hheight_MWDC[2]=0.8*Hlength_MWDC[2];//The half height of the 3rd MWDC box.

	TGeoBBox* MWDC_geo=nullptr;
	TGeoVolume* MWDC=nullptr;
	//TGeoRotation* MWDC_rot1=new TGeoRotation("",90+RtoD(theta3),0,90,90,+RtoD(theta3),0);
	TGeoRotation *gRot = new TGeoRotation();
	gRot->RotateX(0.);
	gRot->RotateY(15.0);
	gRot->RotateZ(0.);
	TGeoRotation* MWDC_rot2=new TGeoRotation("",90-RtoD(theta3),0,90,90,-RtoD(theta3),0);
	TGeoCombiTrans* MWDC_combi1=nullptr;
	TGeoCombiTrans* MWDC_combi2=nullptr;
	for(int i=0;i<3;i++){
		MWDC_geo=new TGeoBBox("MWDC_geo",Hlength_MWDC[i]/2.,Hheight_MWDC[i]/2.,thickness_MWDC/2.);
		MWDC=new TGeoVolume("MWDC",MWDC_geo,MWDCVolMed);
		MWDC->SetLineColor(kYellow-2);
		MWDC_combi1=new TGeoCombiTrans(Hlength_MWDC[0]+i*40.,0,i*150+300., gRot);
		//MWDC_combi1=new TGeoCombiTrans((xc[i]-x_c)*Tan(theta3),0,xc[i], MWDC_rot1);
		//MWDC_combi2=new TGeoCombiTrans(-(xc[i]-x_c)*Tan(theta3),0,xc[i], MWDC_rot2);
		mwdc->AddNode(MWDC, i, MWDC_combi1);
		//mwdc->AddNode(MWDC, i+3, MWDC_combi2);
	}
	/*
		MWDC_geo=new TGeoBBox("MWDC_geo",Hlength_MWDC[0],Hheight_MWDC[0],thickness_MWDC/2.);
		MWDC=new TGeoVolume("MWDC",MWDC_geo,MWDCVolMed);
		MWDC->SetLineColor(kYellow-2);
		MWDC_combi1=new TGeoCombiTrans((x[0]-x_c)*Tan(theta3),0,x[0], MWDC_rot1);
		MWDC_combi2=new TGeoCombiTrans(-(x[0]-x_c)*Tan(theta3),0,x[0], MWDC_rot2);
		mwdc->AddNode(MWDC, 0, MWDC_combi1);
	*/

	cout<<"Voxelizing."<<endl;
	topMWDC->Voxelize("");
	gGeoMan->CloseGeometry();
	topMWDC->Draw();
	gGeoMan->CheckOverlaps(0.001);
	gGeoMan->PrintOverlaps();
	gGeoMan->Test();

	TFile* outfile = TFile::Open(FileName,"RECREATE");
	topMWDC->Write();
	outfile->Close();

	TFile* outfile1 = TFile::Open(FileName1,"RECREATE");
	gGeoMan->Write();
	outfile1->Close();
}

void create_materials_from_media_file()
{
  // Use the FairRoot geometry interface to load the media which are already defined
  FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
  FairGeoInterface* geoFace = geoLoad->getGeoInterface();
  //TString geoPath = gSystem->Getenv("VMCWORKDIR");
  TString geoFile = geoPath + "/geometry/media.geo";
  geoFace->setMediaFile(geoFile);
  geoFace->readMedia();
  // Read the required media and create them in the GeoManager
  FairGeoMedia* geoMedia = geoFace->getMedia();
  FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();

  FairGeoMedium* air              = geoMedia->getMedium("air");
  FairGeoMedium* GEMmixture     = geoMedia->getMedium("GEMmixture");
  FairGeoMedium* CO2		= geoMedia->getMedium("carbondioxide");
  FairGeoMedium* argon		= geoMedia->getMedium("argon");
  FairGeoMedium* oxygen		= geoMedia->getMedium("oxygen");
  FairGeoMedium* nitrogen	= geoMedia->getMedium("nitrogen");
  FairGeoMedium* helium		= geoMedia->getMedium("helium");

  // include check if all media are found

  geoBuild->createMedium(air);
   cout<<"here"<<endl;
  geoBuild->createMedium(GEMmixture);
  geoBuild->createMedium(CO2);
  geoBuild->createMedium(argon);
//  geoBuild->createMedium(oxygen);
//  geoBuild->createMedium(nitrogen);
//  geoBuild->createMedium(helium);
   cout<<"here"<<endl;
}
